home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1996 September / MACPOWER-1996-09.ISO.7z / MACPOWER-1996-09.ISO / 第2特集:プラグイン大集合 / PIC2 Save / p2load.c < prev    next >
Text File  |  1995-01-16  |  15KB  |  737 lines

  1. /*
  2.  *    PIC2 高圧縮/ベタフォーマットの展開 by やなぎさわ
  3.  *  int->long by Banken
  4.  *
  5.  */
  6.  
  7.  
  8. #include "pic2.h"
  9.  
  10. /* 現在のP2の中の変数のコピー (^^; /下手するとかえって効率が悪い (^^;
  11.  * ようはp2構造体から使うとキャストの嵐になるのでそれが面倒
  12.  */
  13.  
  14. static ushort aa;
  15. static ushort dd;
  16. static char cache_hit_c;
  17. static ushort bit_buf;
  18. static short n_bit_buf;
  19. static uchar *fbufp;
  20. static long n_fbuf;
  21. static P2 *p2;
  22. static pix *vram_prev;
  23. static pix *vram_now;
  24. static pix *vram_next;
  25. static schar *flag_now;
  26. static schar *flag_next;
  27. static schar *flag2_now;
  28. static schar *flag2_next;
  29. static schar *flag2_next2;
  30. static pix  (* cache)[N_COLOR_CACHE+1];
  31. static ushort *cache_pos;
  32. static ushort *mulu_tab;
  33.  
  34. static short ynow;
  35.  
  36. static pix (*read_color)( pix x);
  37.  
  38. /* エラー時の脱出用 */
  39. static jmp_buf jmp_env;
  40.  
  41. /*
  42.  * ファイルから 1バイトデータを読み込む
  43.  */
  44. static uchar            /* 読み込んだ値 */
  45. load_char( void)
  46. {
  47.     /* バッファが空かをチェックして空の時は次のデータをバッファに読み込む。 */
  48.     if ( --n_fbuf <= 0) {
  49.         /* バッファのポインタをバッファの先頭に戻して */
  50.         fbufp = p2->fbuf;
  51.  
  52.         /* バッファにデータを読み込む */
  53.         n_fbuf = read_file2( p2, fbufp, N_FBUF);
  54.  
  55.         /* もう無しだとエラーにする
  56.          * 実際のブロック長でチェックされていない (^^;
  57.          * (続きのブロックを読み込んでいてもエラーにならない)
  58.          */
  59.         if ( n_fbuf == 0) {
  60.             p2errno = p2->errno = P2E_FEOF;
  61.             longjmp( jmp_env, 1);
  62.         }
  63.     }
  64.     /* バッファからデータをひとつ取って終わり */
  65.     return ( *fbufp++);
  66. }
  67.  
  68. /*
  69.  * 1ビット読み込む 
  70.  */
  71. #define    load_bit() (                                            ¥
  72.         (n_bit_buf /= 2) == 0                                    ¥
  73.             ? ((bit_buf = load_char()) & (n_bit_buf = 0x80))     ¥
  74.             : (bit_buf & n_bit_buf))
  75.  
  76. /* 
  77.  * 算術圧縮から1ビット復元 
  78.  */
  79. short
  80. bit_decode(
  81.     long    c            /* 確率空間 */
  82.     )
  83. {
  84.     ushort pp = mulu_tab[(aa & 0x7f00) / 2 + c];
  85.  
  86.     if ( dd >= pp) {
  87.         dd -= pp;
  88.         aa -= pp;
  89.  
  90.         while ( (short)aa >= 0) {
  91.             dd *= 2;
  92.             if ( load_bit()) dd++;
  93.             aa *= 2;
  94.         }
  95.         return ( 1);
  96.     
  97.     } else {
  98.         aa = pp;
  99.  
  100.         while ( (short)aa >= 0) {
  101.             dd *= 2;
  102.             if ( load_bit()) dd++;
  103.             aa *= 2;
  104.         }
  105.         return ( 0);
  106.  
  107.     }
  108. }
  109.  
  110. /*
  111.  * 確立空間 cで 0..255の数値を得る
  112.  * なお c..c+7 にてビット長さを得る
  113.  * c+8..c+14でビット分だけ各ビットを得る
  114.  */
  115. short
  116. nn_decode( long c)
  117. {
  118.     long n;
  119.  
  120.     if ( bit_decode( c)) {
  121.         /* n < 1 */
  122.         n = 0;
  123.  
  124.     } else if ( bit_decode( c + 1)) {
  125.         /* n < 1 + 2 */
  126.         n = 1;
  127.         if ( bit_decode( c + 8)) n += 1;
  128.  
  129.     } else if ( bit_decode( c + 2)) {
  130.         /* n < 1 + 2 + 4 */
  131.         n = 1 + 2;
  132.         if ( bit_decode( c + 8)) n += 1;
  133.         if ( bit_decode( c + 9)) n += 2;
  134.  
  135.     } else if ( bit_decode( c + 3)) {
  136.         /* n < 1 + 2 + 4 + 8 */
  137.         n = 1 + 2 + 4;
  138.         if ( bit_decode( c + 8)) n += 1;
  139.         if ( bit_decode( c + 9)) n += 2;
  140.         if ( bit_decode( c + 10)) n += 4;
  141.  
  142.     } else if ( bit_decode( c + 4)) {
  143.         /* n < 1 + 2 + 4 + 8 + 16 */
  144.         n = 1 + 2 + 4 + 8;
  145.         if ( bit_decode( c + 8)) n += 1;
  146.         if ( bit_decode( c + 9)) n += 2;
  147.         if ( bit_decode( c + 10)) n += 4;
  148.         if ( bit_decode( c + 11)) n += 8;
  149.  
  150.     } else if ( bit_decode( c + 5)) {
  151.         /* n < 1 + 2 + 4 + 8 + 16 + 32 */
  152.         n = 1 + 2 + 4 + 8 + 16;
  153.         if ( bit_decode( c + 8)) n += 1;
  154.         if ( bit_decode( c + 9)) n += 2;
  155.         if ( bit_decode( c + 10)) n += 4;
  156.         if ( bit_decode( c + 11)) n += 8;
  157.         if ( bit_decode( c + 12)) n += 16;
  158.  
  159.     } else if ( bit_decode( c + 6)) {
  160.         /* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 */
  161.         n = 1 + 2 + 4 + 8 + 16 + 32;
  162.         if ( bit_decode( c + 8)) n += 1;
  163.         if ( bit_decode( c + 9)) n += 2;
  164.         if ( bit_decode( c + 10)) n += 4;
  165.         if ( bit_decode( c + 11)) n += 8;
  166.         if ( bit_decode( c + 12)) n += 16;
  167.         if ( bit_decode( c + 13)) n += 32;
  168.  
  169.     } else if ( bit_decode( c + 7)) {
  170.         /* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 */
  171.         n = 1 + 2 + 4 + 8 + 16 + 32 + 64;
  172.         if ( bit_decode( c + 8)) n += 1;
  173.         if ( bit_decode( c + 9)) n += 2;
  174.         if ( bit_decode( c + 10)) n += 4;
  175.         if ( bit_decode( c + 11)) n += 8;
  176.         if ( bit_decode( c + 12)) n += 16;
  177.         if ( bit_decode( c + 13)) n += 32;
  178.         if ( bit_decode( c + 14)) n += 64;
  179.  
  180.     } else {
  181.         n = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128;
  182.     }
  183.     return ( n);
  184. }
  185.  
  186. /*
  187.  * 連鎖をよむ
  188.  */
  189. static void
  190. expand_chain( long x, pix cc)
  191. {
  192.  
  193.     /* 現地点がどの連鎖上にあったかで確立空間を変える、そのテーブル */
  194.     static const ushort c_tab[] = {
  195.         80 + 6 * 5,    /* -5 */
  196.         80 + 6 * 4,
  197.         80 + 6 * 3,
  198.         80 + 6 * 2,
  199.         80 + 6 * 1,
  200.         80 + 6 * 0,    /* 0  */
  201.         80 + 6 * 0,    /* 1  */
  202.     };
  203.     ushort b = c_tab[ flag_now[ x] + 5];
  204.  
  205.     if ( ! bit_decode( b++)) {
  206.         if ( bit_decode( b++))      {    /* 下 */
  207.             vram_next[x    ] = cc;
  208.             flag_next[x    ] = -1;
  209.         } else if ( bit_decode( b++)) { /* 左 */
  210.  
  211.             vram_next[x - 1] = cc;
  212.             flag_next[x - 1] = -2;
  213.  
  214.         } else if ( bit_decode( b++)) { /* 右 */
  215.             vram_next[x + 1] = cc;
  216.             flag_next[x + 1] = -3;
  217.  
  218.         } else if ( bit_decode( b++)) { /* 左2 */
  219.             vram_next[x - 2] = cc;
  220.             flag_next[x - 2] = -4;
  221.  
  222.         } else {            /* 右2 */
  223.              vram_next[x + 2] = cc;
  224.             flag_next[x + 2] = -5;
  225.  
  226.         }
  227.     }
  228. }
  229.  
  230.  
  231. /*
  232.  * 空間'c'で'bef'に対しての変化分を読む
  233.  * 01234567890123456789012345678901
  234.  *             +                    前の位置が12だと
  235.  *          64201357     7の変位で 16になる
  236.  */
  237. static ushort
  238. getnum15( long c, long bef)
  239. {
  240.     ushort    n;
  241.  
  242.     n = nn_decode( c);
  243.     if ( bef >= 16) {
  244.         if ( n > (31 - bef) * 2) n = 31 - n;
  245.         else if ( n & 1) n = n / 2 + bef + 1;
  246.         else n = bef - n / 2;
  247.     } else {
  248.         if ( n > bef * 2) n = n;
  249.         else if ( n & 1) n = n / 2 + bef + 1;
  250.         else n = bef - n / 2;
  251.     }
  252.     return ( n);
  253. }
  254.  
  255. static short
  256. getnum24( long c, long bef)
  257. {
  258.     ushort    n;
  259.  
  260.     n = nn_decode( c);
  261.     if ( bef >= 128) {
  262.         if ( n > (255 - bef) * 2) n = 255 - n;
  263.         else if ( n & 1) n = n / 2 + bef + 1;
  264.         else n = bef - n / 2;
  265.     } else {
  266.         if ( n > bef * 2) n = n;
  267.         else if ( n & 1) n = n / 2 + bef + 1;
  268.         else n = bef - n / 2;
  269.     }
  270.     return ( n);
  271. }
  272.  
  273. /*
  274.  * 16(8)bit色の書き出し
  275.  */
  276. static uchar
  277. read_color8( void)
  278. {
  279.     uchar *cache8 = (uchar *)cache_pos; /* ^^; */
  280.     long i,n;
  281.     uchar cc;
  282.     
  283.     n = nn_decode( 32);
  284.     cc = cache8[ n];
  285.     for ( i = n; i > 0; i--) {
  286.         cache8[ i] = cache8[ i - 1];
  287.     }
  288.     cache8[ 0] = cc;
  289.     return ( cc);
  290. }
  291.  
  292. #define    N_CACHE8_S    5
  293. #define N_CACHE8    (1<<N_CACHE8_S)
  294.  
  295. static pix
  296. read_color16( pix x)
  297. {
  298.     pix cc;
  299.     long i,k,n;
  300.     
  301.     k = vram_now[ x - 1] & 255;
  302.  
  303.     if ( bit_decode( cache_hit_c)) {
  304.         /* はずれ */
  305.         cache_hit_c = 16;
  306.  
  307.         cc = read_color8();
  308.         cc = (cc << 8) + read_color8();
  309.         for ( i = N_CACHE8 - 1; i > 0; i--) {
  310.             cache[k][ i] = cache[k][ i - 1];
  311.         }
  312.         cache[k][ 0] = cc;
  313.         
  314.         n = 32;
  315.     } else {
  316.         cache_hit_c = 15;
  317.  
  318.         n = nn_decode( 17);
  319.         cc = cache[ k][ n];
  320.         cache[k][n] = cache[k][n/2];
  321.         cache[k][n/2] = cache[k][0];
  322.         cache[k][0] = cc;
  323.     }
  324.     /* printf("%d/%d:%ld,%d,%d¥n", ynow, x, cc, k, n); */
  325.     
  326.     return ( cc);
  327. }
  328.  
  329. /*
  330.  * 15bit色の読み込み
  331.  */
  332. pix
  333. read_color15( pix x)
  334. {
  335.     pix c1,c2,cc;
  336.     ushort i,j,k,m;
  337.     short r,g,b;
  338.     short r0,g0,b0;
  339.  
  340.     c1 = vram_prev[x];
  341.  
  342.     /*    green             red          blue */
  343.     k = ((c1 / 128) & 0x1c0) + ((c1 / 32) & 0x38) + ((c1 / 8) & 7);
  344.  
  345.     if ( bit_decode( cache_hit_c)) {
  346.         /* はずれ */
  347.         
  348.         cache_hit_c = 16;
  349.  
  350.         c2 = vram_now[ x - 1];
  351.         g = ((c1 & 0xf800) + (c2 & 0xf800)) >> 12;
  352.         r = ((c1 & 0x07c0) + (c2 & 0x07c0)) >>  7;
  353.         b = ((c1 & 0x003e) + (c2 & 0x003e)) >>  2;
  354.  
  355.         g0 = getnum15( 32, g);
  356.         r = r + g0 - g;
  357.         if ( r > 31) r = 31;
  358.         else if ( r < 0) r = 0;
  359.  
  360.         b = b + g0 - g;
  361.         if ( b > 31) b = 31;
  362.         else if ( b < 0) b = 0;
  363.         r0 = getnum15( 48, r);
  364.         b0 = getnum15( 64, b);
  365.         cache_pos[k] = j = (cache_pos[k] - 1) & 31;
  366.         cache[k][j] = cc = (g0 << 11) + (r0 << 6) + (b0 << 1);
  367.     } else {
  368.         cache_hit_c = 15;
  369.         j = nn_decode( 17);
  370.         m = cache_pos[k];
  371.         i = (m + j / 2) & 31;
  372.         j = (m + j) & 31;
  373.  
  374.         cc = cache[k][j];
  375.         cache[k][j] = cache[k][i];
  376.         cache[k][i] = cache[k][m];
  377.         cache[k][m] = cc;
  378.     }
  379.     return ( cc);
  380. }
  381.  
  382. pix
  383. read_color24( pix x)
  384. {
  385.     pix c1,c2,cc;
  386.     ushort i,j,k,m;
  387.     long r, g, b, g0;
  388.  
  389.     c1 = vram_prev[x];
  390.  
  391.     /*    red           green          blue */
  392.     k = ((c1 >> 15) & 0x1c0) + ((c1 >> 10) & 0x38) + ((c1 >> 5) & 7);
  393.  
  394.     if ( bit_decode( cache_hit_c)) { /* はずれ */
  395.         cache_hit_c = 16;
  396.  
  397.         c2 = vram_now[ x - 1];
  398.         g = ((c1 & 0x00ff00) + (c2 & 0x00ff00)) >> 9;
  399.         g0 = getnum24( 32, g);
  400.  
  401.         r = ((c1 & 0xff0000) + (c2 & 0xff0000) >> 17) + g0 - g;
  402.         if ( r > 255) r = 255;
  403.         else if ( r < 0) r = 0;
  404.         r = getnum24( 48, r);
  405.  
  406.         b = (((c1 & 0x0000ff) + (c2 & 0x0000ff)) >> 1) + g0 - g;;
  407.         if ( b > 255) b = 255;
  408.         else if ( b < 0) b = 0;
  409.         b = getnum24( 64, b);
  410.  
  411.         cache_pos[k] = j = (cache_pos[k] - 1) & 31;
  412.         cache[k][j] = cc = (r << 16) + (g0 << 8) + b;
  413. //        assert(( cc & 0xff000000) == 0);
  414.     } else {
  415.         cache_hit_c = 15;
  416.  
  417.         j = nn_decode( 17);
  418.         m = cache_pos[k];
  419.         i = (m + j / 2) & 31;
  420.         j = (m + j) & 31;
  421.  
  422.         cc = cache[k][j];
  423.         cache[k][j] = cache[k][i];
  424.         cache[k][i] = cache[k][m];
  425.         cache[ k][m] = cc;
  426.     }
  427.     return ( cc);
  428. }
  429.  
  430. /* 構造体アクセスをケチするため */
  431.  
  432. static void
  433. para_out( void)
  434. {
  435.     fbufp = p2->fbufp;
  436.     n_fbuf = p2->n_fbuf;
  437.     bit_buf = p2->bit_buf;
  438.     n_bit_buf = p2->n_bit_buf;
  439.     aa = p2->aa;
  440.     dd = p2->dd;
  441.     cache_hit_c = p2->cache_hit_c;
  442.     read_color = (pix (*)( pix)) p2->func;
  443.  
  444.     ynow = p2->ynow;
  445.  
  446.     vram_prev = p2->vram_prev + 4;
  447.     vram_now = p2->vram_now + 4;
  448.     vram_next = p2->vram_next + 4;
  449.     flag_now = p2->flag_now + 4;
  450.     flag_next = p2->flag_next + 4;
  451.     flag2_now = p2->flag2_now + 4;
  452.     flag2_next = p2->flag2_next + 4;
  453.     flag2_next2 = p2->flag2_next2 + 4;
  454.     cache = p2->cache;
  455.     cache_pos = p2->cache_pos;
  456.     mulu_tab = p2->mulu_tab;
  457. }
  458.  
  459. static void
  460. para_in( void)
  461. {
  462.     void *p;
  463.     
  464.     p2->fbufp = fbufp;
  465.     p2->n_fbuf = n_fbuf;
  466.     p2->bit_buf = bit_buf;
  467.     p2->n_bit_buf = n_bit_buf;
  468.     p2->aa = aa;
  469.     p2->dd = dd;
  470.     p2->cache_hit_c = cache_hit_c;
  471.     p2->func = (pix (*)(pix))read_color;
  472.  
  473.     p = p2->vram_prev;
  474.     p2->vram_prev = p2->vram_now;
  475.     p2->vram_now = p2->vram_next;
  476.     p2->vram_next = p;
  477.  
  478.     p = p2->flag_now;
  479.     p2->flag_now = p2->flag_next;
  480.     p2->flag_next = p;
  481.     
  482.     p = p2->flag2_now;
  483.     p2->flag2_now = p2->flag2_next;
  484.     p2->flag2_next = p2->flag2_next2;
  485.     p2->flag2_next2 = p;
  486.  
  487.     p2->ynow = ynow;
  488. }
  489.  
  490. /* 算術版の1ライン展開 */
  491.  
  492. static long
  493. line_expand( P2 *pp2, pix **line)
  494. {
  495.     long ymax;
  496.     long x,xw;
  497.     pix cc;
  498.  
  499.     if ( setjmp( jmp_env) != 0) return ( -1);
  500.  
  501.     p2 = pp2;
  502.     para_out(); /* パラメータの取り出し */
  503.     ymax = SHORT2short( p2->blk.y_wid) - 1;
  504.  
  505.     if ( ynow > ymax) return ( -2); /* おわりだよん */
  506.  
  507.     xw = SHORT2short( p2->blk.x_wid);
  508.     if ( SHORT2short( p2->header.depth) == 8) xw = (xw + 1) / 2;
  509.     
  510.     /* 前のラインの右端を今のラインの左端のひとつ外にセット */
  511.     if ( ynow == 0) {
  512.         cc = 0;
  513.     } else {
  514.         if ( SHORT2short( p2->header.depth) == 8) {
  515.             cc = vram_prev[ xw * 2 - 2];
  516.             cc = cc * 256 + vram_prev[ xw * 2 - 1];
  517.         } else {
  518.             cc = vram_prev[ xw - 1];    /* ひとつ前の色 */
  519.         }
  520.     }
  521.     
  522.     vram_now[-1] = cc;
  523.  
  524.     /* 変化点ようフラグをクリア */
  525.     memset( flag_next, 0, xw * sizeof( flag_next[0]));
  526.  
  527.     /* 位置の確立空間ようのフラグをクリア */
  528.     memset( flag2_next2, 0, xw * sizeof( flag2_next2[0]));
  529.  
  530.     for ( x = 0; x < xw; x++) {
  531.         schar a = flag_now[x];
  532.         if ( a < 0) {
  533.             cc = vram_now[x];
  534.             if ( ynow < ymax) expand_chain( x, cc);
  535.         } else if ( bit_decode( flag2_now[x])) {
  536.             /* 変化点の回りの確立空間を調整*/
  537.             flag2_now[ x + 1]++;
  538.             flag2_now[ x + 2]++;
  539.             flag2_next[  x - 1]++;
  540.             flag2_next[  x    ]++;
  541.             flag2_next[  x + 1]++;
  542.             flag2_next2[ x - 1]++;
  543.             flag2_next2[ x    ]++;
  544.             flag2_next2[ x + 1]++;
  545.  
  546.             vram_now[ x] = cc = read_color( (pix)x);
  547.             if ( ynow < ymax) expand_chain( x, cc);
  548.         } else {
  549.             vram_now[x] = cc;
  550.         }
  551.     }
  552.     if ( line != NULL) {
  553.         if ( SHORT2short( p2->header.depth) == 8) {
  554.             long i;
  555.             
  556.             for ( i = xw - 1; i >= 0; i--) {
  557.                 ushort c = vram_now[i];
  558.                 vram_now[ i * 2 + 1] = c & 255;
  559.                 vram_now[ i * 2] = c / 256;
  560.             }
  561.         }
  562.         *line = vram_now;
  563.     }
  564.     ynow++;
  565.     para_in();    /* パラメータ戻す */
  566.  
  567.     return ( ynow - 1);
  568. }
  569.  
  570. /* 算術版の展開部の初期化 */
  571. long
  572. p2ss_ld_init( P2 *pp2)
  573. {
  574.     ushort p2b[512];
  575.  
  576.     long i,xw;
  577.  
  578.     p2 = pp2;
  579.     p2->ynow = 0; /* 0 ラインからね */
  580.  
  581.     /* 色数に応じた色読み込み関数セット */
  582.     switch ( SHORT2short( p2->header.depth)) {
  583.     case 24:
  584.         p2->func = (pix (*)(pix))read_color24;
  585.         break;
  586.     case 15:
  587.         p2->func = (pix (*)(pix))read_color15;
  588.         break;
  589.     case 8:
  590.         p2->func = (pix (*)(pix))read_color16;
  591.         break;
  592.     default:
  593.         p2errno= p2->errno = P2E_BADFORM;
  594.         return ( -1);
  595.     }
  596.     /* 次ライン展開ようの関数セット */
  597.     p2->nextline = line_expand;
  598.  
  599.     /* ブロックの頭だし */
  600.     seek_file( p2, p2->blk_pos + SIZE_OF_BLK);
  601.  
  602.     /* キャッシュとフラグ関係のクリア */
  603.     xw = SHORT2short( p2->blk.x_wid);
  604.     l_memset( p2->cache, 0, 8 * 8 * (long)sizeof( p2->cache[0]));
  605.  
  606.     memset( p2->flag_now, 0, xw * sizeof( flag_now[0]));
  607.     memset( p2->flag2_now, 0, 8 + xw * sizeof( flag2_now[0]));
  608.     memset( p2->flag2_next, 0, 8 + xw * sizeof( flag2_next[0]));
  609.  
  610.     if ( SHORT2short( p2->header.depth) == 8) {
  611.         uchar *cache8 = (uchar *)p2->cache_pos;
  612.  
  613.         for ( i = 0; i < 256; i++) cache8[i] = i;
  614.     } else {
  615.         memset( p2->cache_pos, 0, 8 * 8 * 8 * sizeof( p2->cache_pos[0]));
  616.     }
  617.  
  618.     /* 確立テーブルの読み込み */
  619.     for ( i = 0; i < N_CONTEXT; i++) {
  620.         p2b[i] = read_short( p2);
  621.     }
  622.     /* 掛け算テーブルの作成 */
  623.     for ( i = 0; i < 16384; i++) {
  624.         p2->mulu_tab[i] = (long)(i / 128 + 128) * p2b[i & 127] / 256;
  625.         if ( p2->mulu_tab[i] == 0) p2->mulu_tab[i] = 1;
  626.     }
  627.     /* 各種変数の初期化 */
  628.     n_bit_buf = 0;
  629.     n_fbuf = 0;
  630.     bit_buf = 0;
  631.     p2->aa = 0xffffu;
  632.     p2->dd = 0;
  633.     for ( i = 0; i < 16; i++) {
  634.         p2->dd *= 2;
  635.         if ( load_bit()) p2->dd |= 1;
  636.     }
  637.     p2->fbufp = fbufp;
  638.     p2->bit_buf = bit_buf;
  639.     p2->n_bit_buf = n_bit_buf;
  640.     p2->n_fbuf = n_fbuf;
  641.     p2->cache_hit_c = 16;
  642.     return ( 0);
  643. }
  644.  
  645. /* ベタ圧縮の1ライン展開 */
  646. static long
  647. beta_line_expand( P2 *pp2, pix **line)
  648. {
  649.     long i,xw,ymax;
  650.     uchar a,b,c,*p;
  651.     pix *pc;
  652.  
  653.     p2 = pp2;
  654.     ymax = SHORT2short( p2->blk.y_wid) - 1;
  655.     if ( p2->ynow > ymax) return ( -2); /* 終わり */
  656.  
  657.     xw = SHORT2short( p2->blk.x_wid);
  658.  
  659.     p2errno = 0;
  660.     if ( raw_beta == 0) { /* 他圧縮と同じpix並び */
  661.         switch ( SHORT2short( p2->header.depth)) {
  662.         case 24:
  663.             if ( read_file( p2, p2->vram_prev, xw * 3) != xw * 3) return ( -1);
  664.             pc = p2->vram_now;
  665.             p = (uchar *)p2->vram_prev;
  666.             for ( i = 0; i < xw; i++) {
  667.                 a = *p++;    /* R */
  668.                 b = *p++;    /* G */
  669.                 c = *p++;    /* B */
  670.                 *pc++ = ((ulong)a << 16) + ((ulong)b << 8) + c;
  671.             }
  672.             break;
  673.         
  674.         case 15:
  675.             if ( read_file( p2, p2->vram_prev, xw * 2) != xw * 2) return ( -1);
  676.             pc = p2->vram_now;
  677.             p = (uchar *)p2->vram_prev;
  678.             if ( memcmp( p2->blk.id, "P2BM", 4) == 0) {
  679.                 for ( i = 0; i < xw; i++) {
  680.                     a = *p++;
  681.                     b = *p++;
  682.                     *pc++ = ((ulong)a << 8) + b;
  683.                 }
  684.             } else {
  685.                 for ( i = 0; i < xw; i++) {
  686.                     a = *p++;
  687.                     b = *p++;
  688.                     *pc++ = ((ulong)b << 8) + a;
  689.                 }
  690.             }
  691.             break;
  692.             
  693.         case 8:
  694.             if ( read_file( p2, p2->vram_prev, xw) != xw) return ( -1);
  695.             pc = p2->vram_now;
  696.             p = (uchar *)p2->vram_prev;
  697.             for ( i = 0; i < xw; i++) {
  698.                 *pc++ = *p++;
  699.             }
  700.             break;
  701.         }
  702.         *line = p2->vram_now;
  703.     } else { /* ベタ形式そのまま入れる */
  704.         switch ( SHORT2short( p2->header.depth)) {
  705.         case 24:
  706.             if ( read_file( p2, p2->vram_now, xw * 3) != xw * 3) return ( -1);
  707.             break;
  708.         case 15:
  709.             if ( read_file( p2, p2->vram_now, xw * 2) != xw * 2 ) return ( -1);
  710.             break;
  711.         case 8:
  712.             if ( read_file( p2, p2->vram_now, xw) != xw ) return ( -1);
  713.             break;
  714.         }
  715.         *line = p2->vram_now;
  716.     }
  717.     pc = p2->vram_prev;
  718.     p2->vram_prev = p2->vram_now;
  719.     p2->vram_now = p2->vram_next;
  720.     p2->vram_next = pc;
  721.  
  722.     p2->ynow++;
  723.     return ( p2->ynow - 1);
  724. }
  725.  
  726. long
  727. p2b_ld_init( P2 *p2)
  728. {
  729.     p2->ynow = 0;
  730.     p2->nextline = beta_line_expand;
  731.     seek_file( p2, p2->blk_pos + SIZE_OF_BLK);
  732.     return ( 0);
  733. }
  734.  
  735.  
  736. /* eof */
  737.